МИФИ. 17.06.2020

Кайгородов Александр Александрович; Группа: М19-117

Преподаватель: Попов Игорь Викторович

Предмет: Методы обработки экспериментальных данных.

Описание данных

Описание выбранных данных: Представлен набор экспериментальных исследований эффекта антидепрессантов влиять на память человека в зависимости от состояния человека. В качестве испутыемых выступали жители Исландии.

Link: https://www.kaggle.com/steveahn/memory-test-on-drugged-islanders-data

Особенности:

  • Дозировка ранжируется по 3 величинам
  • A, T, S : Xanax, Halicion, Плацебо.

*Дозировки следовали в соотношении 1:1. Воспоминания записывались за 10 минут до начала тестирования Участники тестировались каждый день на протяжении 1 недели

Поставлены утверждения:

  • Препараты долгосрочного применения влияют на работу мозга, возможности памяти человека.

  • Позитивные воспоминания являются более глубокими и объемными для представления.

  • Отрицательные воспоминания требуют больших усилий памяти тогда как положительные более восприимчивы к ложным воспоминаниям.

Участники: 25+, хорошие образование и умственные способности

Контент: Файл с предоставленной информацией содержит информацию об участниках, информацию по лечению на протяжении экспериментов. Контроль проводился по проверке способности человека вспоминать замеренного во времени.

Источник: Данные предосталвены университетом UCLA, Калифорния. Автор утверждает о репрезентативности и действительности полученных данных.

Поставлены задачи:

  • Как сильно влияют антидепрессанты в зависимости от возраста испытуемого?
  • Влияют ли препараты на способность памяти?
  • Проявляется ли эффект плацебо?

Импорт данных

In [1]:
import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns
import plotly.graph_objects as go
import plotly.express as px
import plotly.io as pio
pio.templates.default = "plotly_dark"
from plotly.subplots import make_subplots

from sklearn.utils import shuffle
from scipy import stats

Блок импорта библиотек.

В первой части импорт частоиспользуемых библиотек для работы с числами и таблицами. Специально для манипуляции с информацией и формирования ее в необходимые нам сущности.

Во второй части импорт библиотек реализующих визуальную поддержку в python.

В третей части ипорт привычных библиотек для работы с машинным обучением и статистикой. В дальнейшем будет использоваться импорт метода stats.linregress, который позволяет провести линейный регрессионный анализ и получить коэффициенты описывающей формулы. Способ получения значений реализован при помощи МНК.

При импорте данных получаем следующую таблицу

In [2]:
df = pd.read_csv('Islander_data.csv')
df.head(8)
Out[2]:
first_name last_name age Happy_Sad_group Dosage Drug Mem_Score_Before Mem_Score_After Diff
0 Bastian Carrasco 25 H 1 A 63.5 61.2 -2.3
1 Evan Carrasco 52 S 1 A 41.6 40.7 -0.9
2 Florencia Carrasco 29 H 1 A 59.7 55.1 -4.6
3 Holly Carrasco 50 S 1 A 51.7 51.2 -0.5
4 Justin Carrasco 52 H 1 A 47.0 47.1 0.1
5 Liam Carrasco 37 S 1 A 66.4 58.1 -8.3
6 Ava Durand 35 S 1 A 44.1 56.0 11.9
7 Jamie Durand 38 H 1 A 76.3 74.8 -1.5

Демонстрация типов данных представленных в таблице

In [3]:
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 198 entries, 0 to 197
Data columns (total 9 columns):
 #   Column            Non-Null Count  Dtype  
---  ------            --------------  -----  
 0   first_name        198 non-null    object 
 1   last_name         198 non-null    object 
 2   age               198 non-null    int64  
 3   Happy_Sad_group   198 non-null    object 
 4   Dosage            198 non-null    int64  
 5   Drug              198 non-null    object 
 6   Mem_Score_Before  198 non-null    float64
 7   Mem_Score_After   198 non-null    float64
 8   Diff              198 non-null    float64
dtypes: float64(3), int64(2), object(4)
memory usage: 14.0+ KB

Краткая сводка по предоставленным данным.

In [4]:
data = df.copy()
df.describe()
Out[4]:
age Dosage Mem_Score_Before Mem_Score_After Diff
count 198.000000 198.000000 198.000000 198.000000 198.000000
mean 39.530303 1.989899 57.967677 60.922222 2.954545
std 12.023099 0.818504 15.766007 18.133851 10.754603
min 24.000000 1.000000 27.200000 27.100000 -40.400000
25% 30.000000 1.000000 46.525000 47.175000 -3.175000
50% 37.000000 2.000000 54.800000 56.750000 1.700000
75% 48.000000 3.000000 68.400000 73.250000 5.925000
max 83.000000 3.000000 110.000000 120.000000 49.000000

По полученной сводке можно сделать следующие замечания.

  • Возраст: минимальный возраст среди испытуемых равен 24 года, максимальный 83. Это явно скажется на способностях памяти человека. СКО = 12.023. Среднее арифметическое = 39.5 лет, мода = 37 лет, это заранее заставляет предполагать что распределение по возрасту может быть нормальным. Проверка будет осуществлена далее, визуальным способом.
  • Дозировка: мало информации что бы о чем то рассуждать.

  • Оценка памяти до тестирования: Среднее ~58с, СКО = 15.8, мода = 54с.

  • Оценка памяти после тестирования: Среднее ~61c, СКО = 18.1, мода = 56с.

Сравнивая, можно предположить что применение антидипрессанта в виде преппаратов и плацебо, визуально, может влиять на работу памяти человека

Визуализация данных

In [5]:
plt.figure(figsize=(6,4))
sns.barplot(x='Drug', 
            y='Mem_Score_Before', 
            data=data, 
            order=data.Drug.unique().tolist())
plt.title('Distribution of Drugs')
Out[5]:
Text(0.5, 1.0, 'Distribution of Drugs')

Препараты испытывались в равных колличествах, следовательно, наша выборка может считаться сбалансированной.

In [6]:
fig = px.bar(data, 
             x="age",
             y="Mem_Score_Before", 
             title="Память - возраст (ДО)",
             color_discrete_sequence=['#F42272'])
fig.show()
fig = px.bar(data, 
             x="age", 
             y="Mem_Score_After", 
             title="Память - возраст (ПОСЛЕ)", 
            color_discrete_sequence=['#F42272'])
fig.show()

На графике представлены гистограммы отображающие состав испытуемых расположенном в зависимости оценки памяти от возраста до тестирования. Величина ячейки составляющей столбец прямопропрорциональная относительной величине оценки. По графику можно заметить что большая часть испытуемых принадлежит возрасту 25-55 лет. Явно выраженного показателя зависимости оценки памяти от возраста не очевидна.

In [7]:
plt.figure(figsize=(12,10))


x1, y1 = data['age'], data['Mem_Score_Before']
slope1, intercept1, r_value, p_value, std_err = stats.linregress(x1, y1)
plt.plot(x1, y1, 'o', label='BEFORE', )
plt.plot(x1, intercept1+slope1*x1, 'r', label='reg_before')
plt.xlabel('age')
plt.ylabel('Mem_Score_Before')


x2, y2 = data['age'], data['Mem_Score_After']
slope2, intercept2, r_value, p_value, std_err = stats.linregress(x2, y2)
plt.plot(x2, y2, 'v', label='AFTER')
plt.plot(x2, intercept2+slope2*x2, 'b', label='reg_after')
plt.xlabel('age')
plt.ylabel('Mem_Score_After')

plt.legend()

slope1, slope2 = round(slope1, 3), round(slope2, 3)
intercept1, intercept2 = round(intercept1, 3), round(intercept2, 3)
print(f'Regression before: {slope1}*x + {intercept1}')
print(f'Regression after: {slope2}*x + {intercept2}')
Regression before: 0.087*x + 54.546
Regression after: 0.078*x + 57.829

Анализируя полученный график точечной диаграммы и нанесенной на нее прямых линейной регрессии можно сделать следующие предположения:

  • С ростом возраста испытуемого, в среднем, показатели времени при тестировании памяти растут. Растут, стоит заметить, медленно, но тенденция наблюдается и визуально.

  • При визуальном анализе полученных прямых линейной регрессии, можно предположить что прямые почти параллельные, тогда в целом можно сделать предположение что показатель пересечения (intercept), который разнится ДО и ПОСЛЕ примерно на ~3.3с может быть приблизительной оценкой того на сколько замедлилась скорость работы памяти испытуемых

In [8]:
fig = px.scatter(data, 
             x="age",
             y="Mem_Score_Before", title='Распределение оценки от возраста в виде облака точек (ДО)',
             color_discrete_sequence=['orange'])
fig.show()
fig = px.scatter(data, 
             x="age",
             y="Mem_Score_After", title='Распределение оценки от возраста в виде облака точек (ПОСЛЕ)', 
             color_discrete_sequence=['orange'])
fig.show()

На данной точечной диаграмме уже более заметна возможная тенденция к среднему увеличению способности памяти в зависимости от уменьшения возраста. Зависимость отрицательная. На диаграмме рассеивания для случая замеров после употребления препаратов заметна тенденция повсеместного среднего увеличения времения воспоминаний -> ухуджение показателей памяти, но можно заметить что показатели более молодой части выборки ухудшаются сильнее чем у взрослых

Данные тенденции можно проверить проведя простой анализ "топов" в выборке. Анализ "топов" представлен ниже.

In [9]:
fig1 = px.bar(data.sort_values('age', ascending=False)[:15][::-1], 
             x='Mem_Score_Before', y='first_name',
             title='Обследуемые ТОП 15 по рейтингу памяти (ДО)', 
             text='Mem_Score_Before', 
             orientation='h')
fig1.show()
fig2 = px.bar(data.sort_values('age', ascending=False)[:15][::-1], 
             x='Mem_Score_After', y='first_name',
             title='Обследуемые ТОП 15 по рейтингу памяти (ПОСЛЕ)', 
             text='Mem_Score_After', 
             orientation='h')
fig2.show()

По данному графику можно взглянуть на тенденцию изменения показателей для "топов"

In [10]:
sns.pairplot(data)
Out[10]:
<seaborn.axisgrid.PairGrid at 0x7f2dadc8a110>

Данные графики представлены в виде ознакомительной информации которая лучше помогает понять распределение данных Гистограммы описывают распределение данных, даиграммы рассеяния показывают общее распредление признаком в зависимости с другими

Так же интересно взглянуть на самый левый нижний график, т.к анализ такой зависимости ранее не проводился. Он отображает зависимость изменения показателя отметки за тестирование памяти от возраста испытумых. Взглянем на график подробней

In [11]:
fig = px.scatter(data, 
             x="age",
             y="Diff", title='Распределение оценки от возраста в виде облака точек (ПОСЛЕ)', 
             color_discrete_sequence=['orange'])
fig.show()

fig = px.bar(data,
             x='age', y='Diff',
             title='Обследуемые ТОП 15 по рейтингу памяти (ПОСЛЕ)', 
             text='age', 
             orientation='v')
fig.show()

При визуальном анализе можно сделать выводы:

  • Распределение приближенно похоже на нормальное со смещением в сторону положительных значений.
  • Есть испытуемые которые показали лучшие результаты после тестирования препаратами, но можно сделать скидку на то, что среди испытуемых, часть принимала плацебо в виде сахарной таблетки, а это никак не сказывается на работу мозга (не подразумевается в этой эксперименте), но могло оказать даже позитивной влияние в краткосрочной перспективе
In [12]:
grgs = data.groupby(["Drug","Happy_Sad_group"])[["Mem_Score_After"]].mean().reset_index()

fig = px.bar(grgs[['Drug', 'Mem_Score_After','Happy_Sad_group']].sort_values(
    'Mem_Score_After', ascending=False), 
    y="Mem_Score_After", 
    x="Drug", 
    color='Happy_Sad_group', 
    template='plotly_dark')

fig.show()

Группы по признакам воспоминаний также сбалансированы. Средние показатели для каждой группы и подгруппы:

  • А + S: 69.8
  • A + H: 65.5
  • S + S: 58.3
  • S + H: 58.3
  • T + S: 55.2
  • T + H: 57.9
In [13]:
fig = px.scatter(data, 
                 x="Mem_Score_Before",
                 y="Mem_Score_After", 
                 color="Drug", 
                 facet_col="Drug",
        color_continuous_scale=px.colors.sequential.Viridis, render_mode="webgl")
fig.show()
fig = px.scatter(data, 
                 x="Mem_Score_Before", 
                 y="Mem_Score_After", 
                 color="Happy_Sad_group", 
                 facet_col="Happy_Sad_group",
    color_continuous_scale=px.colors.sequential.Viridis, render_mode="webgl")
fig.show()

На данных диаграммах рассеивания видна тенденция изменения оценок до и после тестирования. Чем сильнее направление большего измененеия облака изменяется от линейной зависимости оценок тем сильнее влияние препаратов. Если это отклонение относительно прямой направлено против часовой стрелки, тобишь к большим значениям коэффициента, то воздействие препаратов сказывается сильнее и ухудшает результаты оценки памяти, в ином случае, полностью зеркально обратная ситуация.

Первый график составлен из трех групп по препаратам.

Второй график составлен из двух групп по типу воспоминаний

Дисперсионный анализ (ANOVA)

Очень часто в экспериментах и исследованиях возникает необходимость сравнить несколько групп между собой. В таком случае мы можем применять однофакторный дисперсионный анализ. Та переменная, которая будет разделять наших испытуемых или наблюдения на группы (номинативная переменная с нескольким градациями, в случае данной задачи это название наркотика) называется независимой переменной. А та количественная переменная, по степени выраженности которой мы сравниваем группы, называется зависимая переменная (в случае данной задачи переменная diff отражающая изменение оценки памяти и представляющая из себя время изменения).

Поставлена задача выяснить, отличаются ли средние изменений оценок памяти при применении препаратов и плацебо. Для возможности применений необходимо удовлетворение следующих условий:

  • результаты наблюдей независимы и являются случайными величинами имеющими нормальное распределение
  • Случайные ошибки распределений подчиняются нормальному распределению
  • Эксперименты равноточны

Поставлена следующая гипотеза

  • H0: m1 = m2 = m3
  • H1: m1 != m2 != m3

Прежде чем приступить к проверке гипотезы, необходимо провести проверку ограничений на применение диспресионного анализа

In [52]:
data_for_anova = pd.DataFrame()
data = shuffle(data)
data_for_anova['A'] = data[data['Drug'] == 'A']['Diff'][:50].to_list()
data_for_anova['T'] = data[data['Drug'] == 'T']['Diff'][:50].to_list()
data_for_anova['S'] = data[data['Drug'] == 'S']['Diff'][:50].to_list()

data_for_anova.plot(figsize=(15,5), grid=True)
plt.ylabel('Diff')
data_for_anova.hist(figsize=(15,10))
Out[52]:
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x7f2da5ea42d0>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x7f2d9fd63910>],
       [<matplotlib.axes._subplots.AxesSubplot object at 0x7f2d9fdb5390>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x7f2d9fda7050>]],
      dtype=object)

По полученным графикам можно утверждать что распределения подчиняются нормальному закону распределения (данное предположение высказано на основе представленного выше графического способа) - следовательно можно воспользоваться диспресионным анализом для проверки поставленных гипотез о среднем

In [15]:
A = data_for_anova['A']
T = data_for_anova['T']
S = data_for_anova['S']

print( 'mean value for drug "A" = ', round(A.mean(), 5))
print( 'mean value for drug "T" = ', round(T.mean(), 5))
print( 'mean value for drug "S" = ', round(S.mean(), 5))

print( 'std for drug "A" = ', round(A.std(), 5))
print( 'std for drug "T" = ', round(T.std(), 5))
print( 'std for drug "S" = ', round(S.std(), 5))
mean value for drug "A" =  9.874
mean value for drug "T" =  -0.634
mean value for drug "S" =  -0.578
std for drug "A" =  14.33948
std for drug "T" =  7.50076
std for drug "S" =  7.83317

полученные значения средних показывают сравнительное сходство "невоздействия" на память человека препарата типа Т и плацебо S. Использование антидепрессанта типа А заметно влияет на работу памяти человека. Дисперсии величин не отличаются более чем в 2 раза. Проведем исследование

In [16]:
N = A.shape[0] + T.shape[0] + S.shape[0] # Общее число элементов
n = A.shape[0] # Число элементов в каждой группе (объемы групп равны)
m = 3          # число групп 

# общее среднее значение
mean_global = (A.mean() + T.mean() + S.mean())/3
print('Общее среднее значение = ', mean_global)

# общая сумма квадратов
def ss(ar, mean):
    return sum([(el-mean)**2 for el in ar])

SST = ss(A, mean_global) + ss(T, mean_global) + ss(S, mean_global)
print('Oбщая сумма квадратов = ', round(SST, 3))

# Общее число свободы 
DF = N - 1
print('Общее число свободы = ', DF)

# Внутригрупповая сумма квадратов
SSW = ss(A, A.mean()) + ss(T, T.mean()) + ss(S, S.mean())
print('Внутригрупповая сумма квадратов = ', round(SSW, 3))

# Число степеней свободы внутригрупповая
DF_W = N - m
print('Число степеней свободы внутригрупповая', DF_W)

# Междгрупповая сумма квадратов 
SSB = n*(A.mean() - mean_global)**2 + n*(T.mean() - mean_global)**2 + n*(S.mean() - mean_global)**2
print('Междгрупповая сумма квадратов = ', round(SSB, 3))

# Число степеней свободы межгрупповая
DF_B = m - 1
print('Число степеней свободы межгрупповая = ', DF_B)
Общее среднее значение =  2.887333333333333
Oбщая сумма квадратов =  19499.886
Общее число свободы =  149
Внутригрупповая сумма квадратов =  15838.794
Число степеней свободы внутригрупповая 147
Междгрупповая сумма квадратов =  3661.092
Число степеней свободы межгрупповая =  2

Для проверки посчитаных значений можно воспользоваться известным свойством: сумма межгрупповой и внутригрупповой суммы квадратов равняется общей сумме квадратов

In [17]:
if (SSW + SSB - SST < 10e-5):
    print("Равенство удовлетворено.")
else:
    print(SSW + SSB, SST)
    print('Равенство нарушено')
    raise ValueError
Равенство удовлетворено.

Для проверки гипотезы можно воспользоваться F-критерием. Необходимо найти значение F критерия.

Число степеней свободы df1 = 2, df2 = 149 (inf) Распределение одностороннее, степень значимости alpha = 0.05

Для указанных параметров, F_theor = 2.9957

Использовались представленные таблицы по ссылке: http://statsoft.ru/home/textbook/default.htm

In [18]:
F = round((SSB/m-1) / (SSW/(N-m)), 4)
print('F-критерий = ', F, '\n\n')

F_theor = 2.9957
if F_theor > F: 
    print(f'{F_theor} > {F}')
    print('Принимаем нулеву гипотезу о равенстве средних')
else:
    print(f'{F_theor} < {F}')
    print('Отклоняем нулевую гипотезу о равенстве средних')
F-критерий =  11.3169 


2.9957 < 11.3169
Отклоняем нулевую гипотезу о равенстве средних

По результатам дисперсионного анализа можно сделать следующий вывод:

Т.к дисперсионный анализ отклоняет гипотезу о равенстве средних, а в опыту принимает участие применение плацебо, то можно отверждать о наличии воздействия антидепрессантов на работу памяти. Если учитывать еще и направление воздействия, то в итоге можно сделать конкретное заключение по применению антидепрессаната типа Xanax (в прошлом, очень популярный в России).

"Антидепрессанты типа Xanax имеют влияние на работу памяти человека увеличивая продолжительность вспоминания информации любого рода" Эффект плацебо не проявляется

Проверим расчеты использованием сторонной библиотеки

Проверим решение при помощи использованя все той же scipy библиотеки. Обработаем данные по алгоритму дисперсионного анализа и по непараметрическому критерию Краскела-Уоллиса.

(Правильность библиотеки не поддается сомнению, т.к ее использование можно заметить повсеместно и разрабаетывается сообществом довольно продолжитьельное время)

In [ ]:
x, y, z = A.to_list(), S.to_list(), T.to_list()
KW     = stats.kruskal(x, y, z)
ANOVA = stats.f_oneway(x, y, z)
In [49]:
print('По дисперсионному анализу получен следующий отчет\n', ANOVA)
print('По критерию Краскела-Уоллиса получен следующий отчет\n', KW)
По дисперсионному анализу получен следующий отчет
 F_onewayResult(statistic=16.989313643585312, pvalue=2.3025989612953732e-07)
По критерию Краскела-Уоллиса получен следующий отчет
 KruskalResult(statistic=19.145583242804065, pvalue=6.959682417030031e-05)

В данных отчетах получены статистический значения критериев.

  • ANOVA 16.989, p-value = 2.3025e-7
  • H 19.146, p-value = 6.9597e-5

p-value - значение вероятности ошибки при отклонении нулевой гипотезы. Следовательно, как мы видем из отчетов, вероятности ошибится очень малы - нулевая гипотеза отклоняется. Данное решение совпадает с получеными расчитаными заключениями при анализе выше. Решение можно считать верным.